package com.md.api.common.utils;

import cn.hutool.core.codec.Base64;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.asymmetric.Sign;
import cn.hutool.crypto.asymmetric.SignAlgorithm;
import com.github.binarywang.wxpay.config.WxPayConfig;
import com.github.binarywang.wxpay.v3.auth.AutoUpdateCertificatesVerifier;
import com.github.binarywang.wxpay.v3.auth.PrivateKeySigner;
import com.github.binarywang.wxpay.v3.auth.WxPayCredentials;
import com.github.binarywang.wxpay.v3.util.PemUtils;
import org.springframework.core.io.ClassPathResource;

import java.io.IOException;
import java.security.*;

/**
 * @author: Eden4J
 * @Description: 微信支付相关工具类
 */
public class WxPayUtil {

    public static String sign(String signStr, PrivateKey privateKey) {
        Sign sign = SecureUtil.sign(SignAlgorithm.SHA256withRSA, privateKey.getEncoded(), null);
        return Base64.encode(sign.sign(signStr.getBytes()));
    }

    public static String buildMessage(String appId, String timeStamp, String nonceStr, String body) {
        return appId + "\n" + timeStamp + "\n" + nonceStr + "\n" + body + "\n";
    }

    public static AutoUpdateCertificatesVerifier getVerifier(WxPayConfig wxPayConfig) throws IOException {
        PrivateKey privateKey = PemUtils.loadPrivateKey(new ClassPathResource("apiclient_key.pem").getInputStream());
        AutoUpdateCertificatesVerifier verifier = new AutoUpdateCertificatesVerifier(
                new WxPayCredentials(wxPayConfig.getMchId(), new PrivateKeySigner(wxPayConfig.getCertSerialNo(), privateKey))
                , wxPayConfig.getApiV3Key().getBytes("utf-8")
        );
        return verifier;
    }

    /**
     * 验证签名
     *
     * @param certificate
     * @param message
     * @param signature
     * @return
     */
    public static boolean verify(AutoUpdateCertificatesVerifier certificate, byte[] message, String signature) {
        try {
            Signature sign = Signature.getInstance("SHA256withRSA");
//            sign.initVerify(certificate.getValidCertificate());
            sign.update(message);
            return sign.verify(java.util.Base64.getDecoder().decode(signature));
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("当前Java环境不支持SHA256withRSA", e);
        } catch (SignatureException e) {
            throw new RuntimeException("签名验证过程发生了错误", e);
        }
    }
}

